import type { ComponentPublicInstance, CSSProperties, ExtractPropTypes, PropType } from 'vue';
import {
  baseProps,
  makeArrayProp,
  makeBooleanProp,
  makeNumberProp,
  makeStringProp,
} from 'wot-design-uni/components/common/props';
import type { FormItemRule } from 'wot-design-uni/components/wd-form/types';

import type { ColumnItem } from '@/components/ea-data-picker-view/src/types';

export const pickerProps = {
  ...baseProps,
  /** label 外部自定义类 */
  customLabelClass: makeStringProp(''),
  /** value 外部自定义类 */
  customValueClass: makeStringProp(''),
  /** pickerView 外部自定义类 */
  customViewClass: makeStringProp(''),
  /** pickerView 外部自定义样式 */
  customViewStyle: {
    type: Object as PropType<CSSProperties>,
    default: {},
  },
  /** 选择器左侧文案 */
  label: String,
  /** 选择器占位符 */
  placeholder: String,
  /** 是否禁用 */
  disabled: makeBooleanProp(false),
  /** 是否只读 */
  readonly: makeBooleanProp(false),
  /** 加载中 */
  loading: makeBooleanProp(false),
  /** 加载中颜色 */
  loadingColor: makeStringProp('#4D80F0'),
  // popup
  /** Popup 自定义根节点样式 */
  popupStyle: {
    type: Object as PropType<CSSProperties>,
    default: {},
  },
  /** Popup 高度 满屏 calc(100vh) */
  popupHeight: makeStringProp('39%'),
  /** 弹出层标题 */
  title: String,
  /** 取消按钮文案 */
  cancelButtonText: String,
  /** 确认按钮文案 */
  confirmButtonText: String,
  /** 显示分割线 */
  divider: makeBooleanProp(true),
  /** 是否必填 */
  required: makeBooleanProp(false),
  /** 尺寸 */
  size: String,
  /** 标签宽度 */
  labelWidth: String,
  /** 使用默认插槽 */
  useDefaultSlot: makeBooleanProp(false),
  /** 使用标签插槽 */
  useLabelSlot: makeBooleanProp(false),
  /** 错误状态 */
  error: makeBooleanProp(false),
  /** 右对齐 */
  alignRight: makeBooleanProp(false),
  /** 确定前校验函数，接收 (value, resolve, picker) 参数，通过 resolve 继续执行 picker，resolve 接收1个boolean参数 */
  beforeConfirm: Function as PropType<PickerBeforeConfirm>,
  /** 点击蒙层关闭 */
  closeOnClickModal: makeBooleanProp(true),
  /** 底部安全区域内 */
  safeAreaInsetBottom: makeBooleanProp(true),
  /** 文本溢出显示省略号 */
  ellipsis: makeBooleanProp(false),
  /** 选项值对应的键名 */
  valueKey: makeStringProp('value'),
  /** 选项文本对应的键名 */
  labelKey: makeStringProp('label'),
  /** 选中项(多选类型为数组) */
  modelValue: {
    type: [String, Number, Array] as PropType<string | number | Array<string | number>>,
    default: '',
  },
  /** 选择器数据，可以为字符串数组，也可以为对象数组 */
  columns: {
    type: Array as PropType<Array<string | number | ColumnItem>>,
    default: () => [],
  },
  /** 自定义展示文案的格式化函数，返回一个字符串 */
  displayFormat: Function as PropType<PickerDisplayFormat>,
  /** 自定义层级 */
  zIndex: makeNumberProp(400),
  /** 表单域 model 字段名，在使用表单校验功能的情况下，该属性是必填的 */
  prop: String,
  /** 表单验证规则，结合wd-form组件使用 */
  rules: makeArrayProp<FormItemRule>(),
  /** 是否在手指松开时立即触发 change 事件 */
  immediateChange: makeBooleanProp(false),
  /** 是否多选 */
  multipleSelect: makeBooleanProp(false),
  /** 反向选择 */
  reverseSelect: makeBooleanProp(true),
  /** 显示清空按钮 */
  clearable: makeBooleanProp(false),
  /**
   * 禁止滚动穿透
   * 。使用组件时，会发现内容部分滚动到底时，继续划动会导致底层页面的滚动，这就是滚动穿透。
   * 目前，组件可以通过 lock-scroll 属性处理部分滚动穿透问题。 但由于小程序和APP平台自身原因，弹窗内容区域仍会出现滚动穿透。 不过，我们为开发者提供了一个推荐方案以完整解决滚动穿透：
   * 可以使用 page-meta 组件动态修改 page-meta 的 overflow 属性。
   * @example ```vue
   * <!-- page-meta 只能是页面内的第一个节点，组件中不能使用。可通过组件的 :popup-show="boolean" 属性引出后在页面组件中设置。 -->
   * <page-meta :page-style="`overflow:${show ? 'hidden' : 'visible'};`" />
   * <wd-popup v-model="show" lock-scroll :safe-area-inset-bottom="true" />
   * ```
   */
  lockScroll: makeBooleanProp(true),
};

export type PickerProps = ExtractPropTypes<typeof pickerProps>;

export type PickerDisplayFormat = (
  item: ColumnItem | ColumnItem[],
  vl: { valueKey: string; labelKey: string },
) => string;

export type PickerBeforeConfirm = (
  value: string | number | (string | number)[],
  resolve: (isPass: boolean) => void,
  picker: any,
) => void;

export type PickerExpose = {
  // 打开picker弹框
  open: () => void;
  // 关闭picker弹框
  close: () => void;
  /**
   * 设置加载状态
   * @param loading 加载状态
   */
  setLoading: (loading: boolean) => void;
};

export type PickerInstance = ComponentPublicInstance<PickerExpose, PickerProps>;
